﻿using EmbeddedSharp.Core;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Zove.Test
{
    [TestClass]
    public class LexerTests
    {
        [TestMethod]
        public void TestComment()
        {
            var l = new Lexer("hello world; #hello world\n\rthis is apple;");

            Assert.AreEqual("hello", l.NextToken().Value);
            Assert.AreEqual("world", l.NextToken().Value);
            Assert.AreEqual(";", l.NextToken().Value);

            Assert.AreEqual("this", l.NextToken().Value);
            Assert.AreEqual("is", l.NextToken().Value);
            Assert.AreEqual("apple", l.NextToken().Value);
            Assert.AreEqual(";", l.NextToken().Value);
        }

        [TestMethod]
        public void TestNextLine()
        {
            var l = new Lexer("class test\n\r{\n\rhello world;\n\r#this is a comment;\n\rfactor a, b;\n\r}");
            Assert.AreEqual("class test", l.NextLine());
            Assert.AreEqual("{", l.NextLine());
            Assert.AreEqual("hello world;", l.NextLine());
            Assert.AreEqual("#this is a comment;", l.NextLine());
        }

        [TestMethod]
        public void TestReadUntil()
        {
            var l = new Lexer("class test\n\r{\n\rhello world;\n\r#this is a comment;\n\rfactor a, b;\n\r}");

            Assert.AreEqual("class test", l.ReadUntil('\r', '\n'));
        }

        [TestMethod]
        public void TestPeekChar()
        {
            var l = new Lexer("class test\n\r{\n\rhello world;\n\r#this is a comment;\n\rfactor a, b;\n\r}");

            Assert.AreEqual('c', l.PeekChar());
        }

        [TestMethod]
        public void TestSkipWhiteSpace()
        {
            var l = new Lexer("\n\r class\n\thello");

            l.SkipWhiteSpace();
            Assert.AreEqual(3, l.Index);
        }

        [TestMethod]
        public void TestNextTokenVerified()
        {
            var l = new Lexer("hello world");

            Assert.AreEqual("hello", l.NextToken("hello").Value);
            Assert.AreEqual("world", l.NextToken("world").Value);
        }

        [TestMethod]
        public void TestNextToken()
        {
            var lexer = new Lexer("a + b - 100");

            Assert.AreEqual("a", lexer.NextToken().Value);
            Assert.AreEqual("+", lexer.NextToken().Value);
            Assert.AreEqual("b", lexer.NextToken().Value);
            Assert.AreEqual("-", lexer.NextToken().Value);
            Assert.AreEqual("100", lexer.NextToken().Value);
        }

        [TestMethod]
        public void TestHasMoreTokens()
        {
            var l = new Lexer("hell world;~!@$%^&*?(){};'/|,_"); //[]:\\.<>

            Assert.IsTrue(l.HasMoreTokens());
            while (l.HasMoreTokens())
            {
                l.NextToken();
            }
        }

        [TestMethod]
        public void TestConstructor()
        {
            try
            {
                var l = new Lexer(string.Empty);
                Assert.IsTrue(false);
            }
            catch
            {
                Assert.IsTrue(true);
            }
        }
    }
}